package com.lyb.ui.controller;


import com.lyb.Utils;
import com.lyb.constant.SystemConstant;
import com.lyb.hardware.AlpacaPCB;
import com.lyb.hardware.cpu.AlpacaRegister;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.util.Duration;

import java.net.URL;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * Cpu页面的控制器
 *
 * @author Dayun Mr.Alpaca
 * @version 1.4.0
 */
public class CpuController implements Initializable {
    @FXML
    public Label systemTimeSign;
    @FXML
    public Label systemTimeLabel;
    @FXML
    public Label pcSign;
    @FXML
    public Label pcLabel;
    @FXML
    public Label pswSign;
    @FXML
    public Label pswLabel;
    @FXML
    public Label irSign;
    @FXML
    public Label irLabel;
    @FXML
    public Label drSign;
    @FXML
    public Label drLabel;
    @FXML
    public Label currentPcbSign;
    @FXML
    public Label currentPcbLabel;
    @FXML
    public Label timeSliceSign;
    @FXML
    public Label timeSliceLabel;
    @FXML
    public TextArea readyQueueText;
    @FXML
    public TextArea blockQueueText;
    @FXML
    public TextArea emptyQueueText;
    @FXML
    public Label readyQueueSign;
    @FXML
    public Label blockQueueSign;
    @FXML
    public Label emptyQueueSign;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        /* 获取各组件动画 */
        KeyFrame systemTimeFrame = getSystemTimeFrame();
        KeyFrame readyQueueFrame = getReadyQueueFrame();
        KeyFrame blockQueueFrame = getBlockQueueFrame();
        KeyFrame emptyQueueFrame = getEmptyQueueFrame();
        KeyFrame currentPcbFrame = getCurrentPcbFrame();
        KeyFrame timeSliceFrame = getTimeSliceFrame();
        KeyFrame pcFrame = getPcFrame();
        KeyFrame pswFrame = getPswFrame();
        KeyFrame irFrame = getIrFrame();
        KeyFrame drFrame = getDrFrame();

        /* 添加动画到时间线 */
        Timeline timeline = new Timeline();
        timeline.getKeyFrames().addAll(systemTimeFrame, readyQueueFrame, blockQueueFrame,
                emptyQueueFrame, currentPcbFrame, timeSliceFrame,
                pcFrame, pswFrame, irFrame, drFrame);
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.setAutoReverse(true);
        timeline.play();
    }

    /**
     * 获取系统时间组件的动画
     *
     * @return 动画
     */
    private KeyFrame getSystemTimeFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            systemTimeLabel.setText("系统" + Utils.getRunningTime());
        });
    }

    /**
     * 获取就绪队列组件的动画
     *
     * @return 动画
     */
    private KeyFrame getReadyQueueFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            StringBuilder content = new StringBuilder();
            for (AlpacaPCB pcb : SystemConstant.MAIN_BOARD.getReadyQueue()) {
                content.append("进程PID: ").append(pcb.getId()).append("\n")
                        .append("可执行文件: ").append(pcb.getPath()).append("\n")
                        .append("进程状态: ").append(pcb.load().getPsw()).append("\n")
                        .append("将要执行的指令: ").append(pcb.load().getIr()).append("\n")
                        .append("----------------------------------------").append("\n");
            }
            readyQueueText.setText(content.toString());
        });
    }

    /**
     * 获取阻塞队列组件的动画
     *
     * @return 动画
     */
    private KeyFrame getBlockQueueFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            StringBuilder content = new StringBuilder();
            for (AlpacaPCB pcb : SystemConstant.MAIN_BOARD.getBlockQueue()) {
                content.append("进程PID: ").append(pcb.getId()).append("\n")
                        .append("可执行文件: ").append(pcb.getPath()).append("\n")
                        .append("进程状态: ").append(pcb.load().getPsw()).append("\n")
                        .append("将要执行的指令: ").append(pcb.load().getIr()).append("\n")
                        .append("----------------------------------------").append("\n");
            }
            blockQueueText.setText(content.toString());
        });
    }

    /**
     * 获取空闲队列组件的动画
     *
     * @return 动画
     */
    private KeyFrame getEmptyQueueFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            StringBuilder content = new StringBuilder();
            for (AlpacaPCB pcb : SystemConstant.MAIN_BOARD.getEmptyQueue()) {
                content.append("进程PID: ").append(pcb.getId()).append("\n")
                        .append("可执行文件: ").append(pcb.getPath()).append("\n")
                        .append("进程状态: ").append(pcb.load().getPsw()).append("\n")
                        .append("将要执行的指令: ").append(pcb.load().getIr()).append("\n")
                        .append("----------------------------------------").append("\n");
            }
            emptyQueueText.setText(content.toString());
        });
    }

    /**
     * 获取当前进程组件的动画
     *
     * @return 动画
     */
    private KeyFrame getCurrentPcbFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            AlpacaPCB pcb = SystemConstant.MAIN_BOARD.getCurrentPcb();
            String content = "";
            if (pcb != null) {
                content = String.valueOf(pcb.getId());
            }
            currentPcbLabel.setText(content);
        });
    }

    /**
     * 获取时间片组件的动画
     *
     * @return 动画
     */
    private KeyFrame getTimeSliceFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            int timeSlice = SystemConstant.MAIN_BOARD.getTimeSliceFromCpu();
            timeSliceLabel.setText(String.valueOf(timeSlice));
        });
    }

    /**
     * 获取PC组件的动画
     *
     * @return 动画
     */
    private KeyFrame getPcFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            AlpacaRegister register = SystemConstant.MAIN_BOARD.getRegisterFromCpu();
            String content = "";
            if (register != null) {
                content = String.valueOf(register.getPc());
            }
            pcLabel.setText(content);
        });
    }

    /**
     * 获取DR组件的动画
     *
     * @return 动画
     */
    private KeyFrame getDrFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            AlpacaRegister register = SystemConstant.MAIN_BOARD.getRegisterFromCpu();
            StringBuilder content = new StringBuilder();
            if (register != null) {
                Map<String, Double> dr = register.getDr();
                for (String key : dr.keySet()) {
                    content.append(key).append("=").append(dr.get(key)).append("\n");
                }
            }
            drLabel.setText(content.toString());
        });
    }

    /**
     * 获取IR组件的动画
     *
     * @return 动画
     */
    private KeyFrame getIrFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            AlpacaRegister register = SystemConstant.MAIN_BOARD.getRegisterFromCpu();
            String content = "";
            if (register != null) {
                content = String.valueOf(register.getIr());
            }
            irLabel.setText(content);
        });
    }

    /**
     * 获取PSW组件的动画
     *
     * @return 动画
     */
    private KeyFrame getPswFrame() {
        return new KeyFrame(Duration.millis(1), event -> {
            AlpacaRegister register = SystemConstant.MAIN_BOARD.getRegisterFromCpu();
            String content = "";
            if (register != null) {
                content = String.valueOf(register.getPsw());
            }
            pswLabel.setText(content);
        });
    }
}
